using System;
using System.Collections.Generic;
using DG.Tweening;
using KissEcs;
using UnityEngine;

/// <summary>
/// BGM,音效控制器
/// </summary>
public  class AudioMgr : Singleton<AudioMgr>, ISystem
{
    public AudioSource audioPlayer;//UI音效播放器
    public AudioSource backGroundMusicPlayer;//BGM播放器
    public Transform skillAudioSourcesParent;
    private readonly Dictionary<string, AudioClip> audioDict = new();
    private readonly Dictionary<string, AudioClip> bgmDict = new();

    private Dictionary<string, AudioSource> skillAudioSources = new();

    private PoolDict skillAudioPool = new();
    protected override void Awake()
    {
        base.Awake();

        skillAudioPool.InitPool("skillAudio", new GameObject());
        
        audioPlayer.loop = false;
        World.AddSystem(this);
    }
    private void Start()
    {
        LoadAllAudio();
        LoadAllBGM();
    }

    /// <summary>
    /// 加载所有音效
    /// </summary>
    public async void LoadAllAudio()
    {
        var all = await AssetLoader.LoadByLabel<AudioClip>(this, "AudioAsset");
        for(int i = 0; i < all.Count; i++)
        {
            audioDict.Add(all[i].name, all[i]);
        }
        Debug.Log("audio load success");
    }

    public async void LoadAllBGM()
    {
        var all = await AssetLoader.LoadByLabel<AudioClip>(this, "BgmAsset");
        for(int i =0; i < all.Count; i++)
        {
            bgmDict.Add(all[i].name, all[i]);
        }
        Debug.Log("Bgm load success");
    }

    public void PlayAudio(string str)
    {
        if(audioDict.TryGetValue(str,out AudioClip clip))
        {
            audioPlayer.clip = clip;
            audioPlayer.Play();
            audioPlayer.volume = Global.ClipVolume;
        }
        else
        {
#if UNITY_EDITOR
            Toast.ShowToast($"请检查输入是否有误,输入为:{str}");
#else
            Debug.LogError("字典中不存在该音效");
#endif
        }
    }

    public void PlayBGM(string str)
    {
        if(bgmDict.TryGetValue(str,out AudioClip clip))
        {
            backGroundMusicPlayer.clip = clip;
            backGroundMusicPlayer.loop = true;
            backGroundMusicPlayer.Play();
            backGroundMusicPlayer.volume = Global.MusicVolume;
        }
        else
        {
#if UNITY_EDITOR
            Toast.ShowToast($"请检查输入是否有误,输入为:{str}");
#else
            Debug.LogError("字典中不存在该音效");
#endif
        }
    }

    public void SmoothSetBGMVolume(float targetVolume)
    {
        backGroundMusicPlayer.DOFade(targetVolume, 1);
        PlayerPrefs.SetFloat("MusicVolume", Global.MusicVolume);
        PlayerPrefs.SetInt("IsM", Convert.ToInt32(Global.IsM));
    }
    public void ChangeBGMVolume()
    {
        backGroundMusicPlayer.volume = Global.MusicVolume;
        // 在小游戏环境中，从音量为0改为1背景音不生效
        if (Global.MusicVolume <= 0)
        {
            backGroundMusicPlayer.Pause();
        }
        else
        {
            backGroundMusicPlayer.Play(0);
        }
        Debug.Log($"ChangeBGMVolume: {Global.MusicVolume}");
        PlayerPrefs.SetFloat("MusicVolume", Global.MusicVolume);
        PlayerPrefs.SetInt("IsM", Convert.ToInt32(Global.IsM));
       
    }
   
    public void ChangeClipVolume()
    {
        PlayerPrefs.SetFloat("ClipVolume", Global.ClipVolume);
        PlayerPrefs.SetInt("IsC", Convert.ToInt32(Global.IsC));
    }

    #region 播放BGM
    public void PlayBGM_Main()
    {
        PlayBGM("main");
    }

    public void PlayBGM_Battle(bool isCoinLevel = false)
    {
        if (isCoinLevel)
        {
            PlayBGM("coinLevel");
        }
        else
        {
            PlayBGM("war");
        }
        
    }

    #endregion

    #region 播放音效方法
    /// <summary>
    /// 点击按钮方法
    /// </summary>
    public void PlayAudio_Click()
    {
        PlayAudio("click");
    } 
    public void PlayAudio_SelectOne()
    {
        PlayAudio("selectOne");
    } 

    /// <summary>
    /// 失败界面调用
    /// </summary>
    public void PlayAudio_Defeat()
    {
        PlayAudio("defeat");
    }
    /// <summary>
    /// 战场中捡到道具调用
    /// </summary>
    public void PlayAudio_Get()
    {
        PlayAudio("get");
    }
    /// <summary>
    /// 战场中击中音效
    /// </summary>
    public void PlayAudio_Hit()
    {
        PlayAudio("hit");
    }
    /// <summary>
    /// 点击导航栏音效
    /// </summary>
    public void PlayAudio_Menu()
    {
        PlayAudio("tapswitching");
    }
    /// <summary>
    /// 开箱音效
    /// </summary>
    public void PlayAudio_OpenBox()
    {
        PlayAudio("openBox");
    }
    /// <summary>
    /// 转盘音效
    /// </summary>
    public void PlayAudio_Run()
    {
        PlayAudio("run");
    }
    /// <summary>
    /// 转盘停止音效
    /// </summary>
    public void PlayAudio_WheelStop()
    {
        PlayAudio("wheelstop");
    }
    /// <summary>
    /// 胜利界面调用
    /// </summary>
    public void PlayAudio_Victory()
    {
        PlayAudio("victory");
    }
    /// <summary>
    /// 完成任务，领取奖励调用
    /// </summary>
    public void PlayAudio_Victory1()
    {
        PlayAudio("victory1");
    }

    /// <summary>
    /// 升级，装备合成/升级，伙伴升星/升级调用
    /// </summary>
    public void PlayAudio_Victory2()
    {
        PlayAudio("victory2");
    }

    /// <summary>
    /// 关卡内升级提示音效
    /// </summary>
    public void PlayAudio_LevelUp()
    {
        PlayAudio("levelup");
    }
    #endregion

    public AudioClip ReturnClip(string str)
    {
        if(audioDict.TryGetValue(str,out AudioClip clip))
        {
            return clip;
        }
        else
        {
            Debug.LogError($"请检查输入是否有误,输入为:{str}");
            return null;
        }
    }

    public void PlaySkillAudio(string audioName, string audioKey = "", bool isLoop = false)
    {
        if (string.IsNullOrEmpty(audioKey))
        {
            audioKey = audioName;
        }
        if (!skillAudioSources.TryGetValue(audioKey, out var audioClip))
        {
            var go = skillAudioPool.Get("skillAudio");
            go.name = audioKey;
            audioClip = go.AddComponent<AudioSource>();
            go.transform.parent = skillAudioSourcesParent;
            skillAudioSources[audioKey] = audioClip;
            audioClip.clip = audioDict[audioName];
            audioClip.volume = Global.ClipVolume;
        }
        audioClip.loop = isLoop;
        audioClip.Play();
    }

    public void StopSkillAudio(string audioKey, bool isDestroy = false)
    {
        if (!skillAudioSources.ContainsKey(audioKey))
        {
            return;
        }
        if (isDestroy)
        {
            skillAudioPool.Put("skillAudio", skillAudioSources[audioKey].gameObject);
            skillAudioSources.Remove(audioKey);
        }
        else
        {
            skillAudioSources[audioKey].Stop();
        }
    }

    public void ClearSkillAudioSources()
    {
        Utils.DestroyAllChildren(skillAudioSourcesParent);
        skillAudioSources.Clear();
    }
}
